--------------------------------------------------------------------------------------------------------------------------------------- 
--版权声明：本demo集源于上海合宙官方技术团队的DEMO（MIT），并参考了合宙开源社区的众多大佬无私分享的代码，包括但不限于 稀饭放姜、Wendal、晨旭等
-- 目前参考到的开源项目有： iRTU（MIT)、LuatOS(MIT)
-- 欲获取更多luat 代码请访问 doc.openluat.com
-- 如果您觉得本demo集包含了未经由您授权的代码，请联系 64034373@qq.com 
---------------------------------------------------------------------------------------------------------------------------------------

-- @模块功能：iRTU固件执行前适配
-- @author miuser
-- @module midemo.irtu_init
-- @license MIT
-- @copyright miuser@luat
-- @release 2020-09-08
--------------------------------------------------------------------------
------------------------iRTU配置信息---------------------------------
--通过修改当前目录的irtu.json，可以对iRTU模块初始状态进行配置
--通过create.getDatalink()函数获取iRTU服务器连接状态 true为已经连接
--通过sys.publish("NET_RAW_MONI",str)向服务器发送数据
--通过 sys.subscribe("NET_RAW_MONI", function(msg) ...end) 接收服务器发送来的数据

--------------------------------------------------------------------------

require "bs"
--以下部分的代码无须用户修改
module(..., package.seeall)
--_G.PRODUCT_KEY = "DPVrZXiffhEUBeHOUwOKTlESam3aXvnR"
--iRTU的缺省配置文件，描述了首次烧写后的iRTU行为
CONFIG="irtuupws.json"
sendPool={}

local function readfile(filename)--打开指定文件并输出内容
    
    local filehandle=io.open(filename,"r")--第一个参数是文件名，第二个是打开方式，'r'读模式,'w'写模式，对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
    if filehandle then          --判断文件是否存在
        local fileval=filehandle:read("*all")--读出文件内容
      if  fileval  then
           print(fileval)  --如果文件存在，打印文件内容
           filehandle:close()--关闭文件
           return fileval
      else 
           print("The file is empty")--文件不存在
      end
    else 
        print("文件不存在或文件输入格式不正确") --打开失败  
    end    
end


local function writevalw(filename,value)--在指定文件中添加内容
    local filehandle = io.open(filename,"w")--第一个参数是文件名，后一个是打开模式'r'读模式,'w'写模式，对数据进行覆盖,'a'附加模式,'b'加在模式后面表示以二进制形式打开
    if filehandle then
        filehandle:write(value)--写入要写入的内容
        filehandle:close()
    else
        log.info("midemo.irtu_adapter","irtu适配文件不存在或文件输入格式不正确") 
    end
end
CONFIG="/lua/"..CONFIG

content=readfile(CONFIG)
config=json.decode(content)
content_modified=json.encode(config)
log.info("updated json",content)
writevalw("/CONFIG.cnf",content)


sys.subscribe("NET_RECV_WAIT_1",function(uid,msg)
    local str =msg
    local echo=0
    log.info("irtu_init","socket received:"..msg) 
    --消除服务器抄送的发送数据
    table.foreach(sendPool,function(i,v) 
        if v==msg then
            log.info("irtu_init","cancelling message:"..v) 
            table.remove(sendPool,i)
            echo=1
        end 
    end)
    --设置最多10个缓冲，超出则按时间清空
    log.info("irtu_init","sendPool len:"..#sendPool)
    todelete=#sendPool-10
    for i=1,todelete do
        table.remove(sendPool,i)
    end
    if (echo==1) then return end
    log.info("irtu_init","going out:"..msg) 
    --透传
    if (str:sub(7,7)=="C") then 
        str=str:sub(40,-3)
        sys.publish("DISPLAY",str)
        sys.publish("NET_RAW_MINO",str)
        sys.publish("NET_RAW_MONI",string.sub(str,1,#str-2).."->OK".."\n\r")
        sys.publish("COM",str.."\n\r")
    --心跳包
    elseif (str:sub(7,7)=="B") then 
        str=str:sub(40,-3)
        --sys.publish("DISPLAY",str)
        sys.publish("NET_BEAT_MINO",str)
        --sys.publish("COM",str.."->OK".."\n\r")    
    --命令
    elseif (str:sub(7,7)=="A") then 
        str=str:sub(40,-3)
        sys.publish("DISPLAY",str)
        sys.publish("NET_CMD_MINO",str)
        sys.publish("NET_CMD_MONI",string.sub(str,1,#str-2).."->OK".."\n\r")
        sys.publish("COM",str.."\n\r")
         -- 串口的数据读完后清空缓冲区
        local splitlist = {}
        string.gsub(str, '[^,]+', function(w) table.insert(splitlist, w) end)
        local count=table.getn(splitlist)
        --sys.publish("UARTIN",str)
        for i=1,#splitlist do 
            splitlist[i]=common.gb2312ToUtf8(splitlist[i])
            splitlist[i]=bs.PIN_MAP(splitlist[i])
        end 
        sys.publish(unpack(splitlist))
        sendQueue = {}
    else       
        return
    end

end)

sys.subscribe("NET_RAW_MONI", function(str)
    totallen=41+str:len()
    local ret=string.format("%04d",totallen).."01".."C".."01"..""..bs.ID..""..""..bs.MM.."".."1234"..str.."05"
    sys.publish("NET_SENT_RDY_1",ret)
    table.insert(sendPool,ret)
    log.info("irtu_init","pooling message:"..ret) 
    log.info("irtu_init","sendPool len:"..#sendPool)
end)

sys.subscribe("NET_HEART_MONI", function(str)
    totallen=41+str:len()
    local ret=string.format("%04d",totallen).."01".."B".."01"..""..bs.ID..""..""..bs.MM.."".."1234"..str.."05"
    sys.publish("NET_SENT_RDY_1",ret)
    table.insert(sendPool,ret)
    log.info("irtu_init","pooling message:"..ret)
    log.info("irtu_init","sendPool len:"..#sendPool) 
end)

sys.subscribe("NET_CMD_MONI", function(str)
    totallen=41+str:len()
    local ret=string.format("%04d",totallen).."01".."A".."01"..""..bs.ID..""..""..bs.MM.."".."1234"..str.."05"
    sys.publish("NET_SENT_RDY_1",ret)
    table.insert(sendPool,ret)
    log.info("irtu_init","pooling message:"..ret) 
    log.info("irtu_init","sendPool len:"..#sendPool)
end)
